Using the console vs. Scripts vs. Markdown vs. R Notebooks
Welcome to using R. This subsection will explain the basics about R.
First, lets discuss the different ways to write R code, as there are (at
least) 5:
- type it directly into the console (generally not recommended)
- save it as a script (better) note that script can refer
to any of the below, but in this case is being used to describe a script
that doesn’t generate a notebook
- save it as an R Markdown (better still) - this allows you to make
beautiful documents
- save it as an R Notebook (arguably better than R Markdown) - this
allows you to make beautiful documents, and is quicker
The Console
At the bottom left of RStudio you should have a console that looks
something like what’s highlighted in red
below:

You can type straight into the console, to get a result. You can
scroll through your previous commands by pressing the up arrow in the
console. Each time code is run in the console it updates the environment
in the top right of R-Studio:

Scripts
The word “script” can be interpreted specifically, to refer to a type
of R file that includes a lot of code, or generally to refer to any file
that includes both R code and code that allows you make a nice looking
report. In this subsection, we will be focusing on “script” as a
particular type of file. To create a script, click on File ->
New File -> R Script

You will then be shown a blank script, in which you can write a
series of functions, and then run them. To run the lines of code, select
a line, and then press CTRL-ENTER, or highlight a chunk of code and then
press CTRL-ENTER. In either case, the code will be sent to the console
and run there.
An advantage of a script over just using the console is that you can
analyse your data in both structured and complex ways which is
difficult if you are typing code directly into the console.
R Markdown
As highlighted above, R Markdown is a type of “script” in the general
sense of the word, but allows you to create beautiful .html notebooks
(.html files are what internet pages are based on). You are in fact
reading an example of what can be produced by R Markdown (and R
Notebooks). To make an R Markdown file, click on File -> New
File -> R Markdown. You will be asked for a title, author
and what output you would like. I would suggest “first markdown”, your
name and “html” as the respective answers. You should then see something
like:

The following points apply to both R Markdown and R
Notebooks
If you look above, you may notice that there are 2 types of code:
Markdown (to write a nice looking report) and R (in grey chunks). I
think these are well explained here: https://www.rstudio.com/wp-content/uploads/2015/02/rmarkdown-cheatsheet.pdf
so I’ll just explain that R Markdowns run all the code in the chunks
each time they generate the output file (e.g. html file). This is
important to know, because R Notebooks do not do
this.
R Notebooks
R Notebooks can be created by clicking on File -> New File
-> R Notebook. They look quite similar to R Markdowns, but
automatically generate the .html output each time you save the
notebook. The output file will be a .nb.html
file in the same folder as your notebook.
Very importantly - the .nb.html
file will be built based on what happened the last time you run each R
chunk. If you never ran the R Chunk, then the nb.html file will not use
the output from that chunk. This makes R Notebooks quicker than
R Markdowns, because you don’t have to generate the output from scratch
each time, but there is a risk of you forgetting to run a chunk after
changing it.
Fundamental’s of R
R allows you to complete calculations, so lets start with that. Type
into your markdown or script
Often, you can use R as a calculator, for example:
5 + 2
It’s helpful to store these calculations into
objects:
a <- 5 + 2 # this is exactly the same as writing a = 5 + 2, but <- is encouraged in R to avoid confusion with other uses of = (e.g. == operator when you are comparing if two values are identical)
# this # is starting a comment, code that will be ignored but allows you to annotate your work
a # to show what the value 7 is now stored in the object "a"
This means that you can compare objects to each other later
b <- 2
b - a
c <- b-a
c # to show what c is
Some advice/rules for Objects:
- You cannot have a space in an object name. “my object” would be an
invalid object name.
- object names are case-sensitive, so if
your object is called “MyObject” you cannot refer to it as
“myobject”.
- “.” and “_” are acceptable characters in variable names.
- you can overwrite objects in the same way that you define an
object
this_object <- 5
this_object # to show what the object value is
this_object <- 10 # overwrites this_object
this_object # should now show 10
- be careful to not give an object the same name as a function! This
will overwrite the function. To check if the name already exists, you
can start typing it and press tab. So typing “t.te” and pressing the tab
will give you “t.test”
Functions
In a variety of coding languages like R, functions
are lines of code you can apply each time you call the function, and
apply it to input to get an output. If
you wanted to make a function that multiplied numbers by 2, it would
look something like:
times_two <- function(input){ # Define your function by stating it's name, and then using <- to describe it
output = input * 2 # creates an output object that is the input object (see line above) x 2
return (output) # gives the output back to the user when they run the function
}
times_two(4) # should give you 8
The great news is that you don’t need to write
functions 99% of the time in R, there are a wide variety of functions
that are available. Some of which will be used in the next section.
Types of Objects
Vectors
Vectors store a series of values. Often these will
be a series of numbers:
numeric_vector = c(1,2,3)
numeric_vector
The “c” above is short for “combine” as you’re combining values
together to make this vector. Strings are values that
have characters (also known as letters) in them. Lets see if we can make
a vector of strings:
string_vector = c("a", "b", "c")
string_vector
Looks like we can. But what happens if you mix strings and numbers in
a vector:
mixed_vector = c("a", 1, "c")
mixed_vector
R seems to be happy to put them into a single vector. But there are
different types of values and vectors, so lets ask R what each type of
(using the “typeof” function) vectors we have
above:
typeof(numeric_vector)
typeof(string_vector)
typeof(mixed_vector)
The numeric vector is a “double” vector. Double
refers to the fact that the numbers can include decimals, as
opposed to integer numbers which have to be whole
numbers. Interestingly, R has assumed the list of numbers should be
double rather than integer, which
seems like the more robust thing to do, as integer numbers can always be
double, but double numbers can’t always be integers.
Data frames
Data frames look like tables, in which you have a
series of columns with headers that describe each
column.
Some data frames are already loaded into RStudio when you run it,
such as the “mpg” dataframe. To look at it, just type in it’s name:
mpg
Note that you may see 2 tables
above, but they should be identical if so
The mpg dataframe has information about a variety of
cars, their manufacturers, models, as described https://ggplot2.tidyverse.org/reference/mpg.html. You
will need to refer to data frames and their columns, the convention for
this being to write data frame$column. Lets do this to see what’s in the
“manufacturer” column:
mpg$manufacturer
Packages
Whilst a lot of the functions you will need are in the base
code that is active by default, you will at times need extra packages of
code to do more powerful things. A commonly used package is ggplot2 [https://ggplot2.tidyverse.org/], which allows you to
make beautiful figures in R. To use ggplot2
use need to install it and then load it from the
library
if(!require(ggplot2)){install.packages("ggplot2")}
library(ggplot2)
Now that you have a package for making beautiful plots, lets learn
about “intelligent copy and paste” to make use of it.
Intelligent copy and paste
People experienced with coding do not write all their
code from memory. They often copy and paste code from the
internet and/or from their old scripts. So, assuming you’ve installed
and loaded ggplot2 as described above, lets copy and paste code from
their website (as of September 2022; https://ggplot2.tidyverse.org/)
ggplot(mpg, aes(displ, hwy, colour = class)) +
geom_point()
Good news is that we have a nice looking figure. But now we need to
work out how to understand the code we’ve copied so that you can apply
it to your own scripts. There’s a lot to unpack, so making the code more
vertical can help you break it down and comment it out.
Using the below and a description of the mpg dataframe (https://ggplot2.tidyverse.org/reference/mpg.html), can
you comment it out
ggplot( # R will keep looking at your code until all the open brackets have been closed)
mpg, #
aes( #
displ, #
hwy, #
colour = class #
)
) + # R will look to the next line if you end a line with +
geom_point() #
Here’s how I would comment it out:
ggplot(
mpg, # dataframe
aes( # aesthetic properties
displ, # x-axis
hwy, # y-axis
colour = class # which column I will base the color on (often "color" is safer spelling in code)
)
) +
geom_point() # what I would like drawn on (as opposed to boxplots, lines, etc.)
Formatting code like above to be clearer to read is useful
when sharing your scripts with other researchers so that they can
understand it!
Now to understand the above code, try running it after changing
lines. For example, what happens if you change the x-axis:
ggplot(
mpg, # dataframe
aes( # aesthetic properties
cty, # x-axis - updated
hwy, # y-axis
colour = class # which column I will base the color on (often "color" is safer spelling in code)
)
) +
geom_point() # what I would like drawn on (as opposed to boxplots, lines, etc.
To make beautiful figures in R, you can largely google the type of
plot you want, copy the example code that the website has, and then swap
in the relevant features for your plot. This principle of copying and
pasting code, (making it vertical to make it legible is not necessary,
but can be helpful), and then editing it to work for your own script is
an essential skill to speed up your coding.
LS0tCnRpdGxlOiAiUiAoU3R1ZGlvKSBiYXNpY3MiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIFVzaW5nIHRoZSBjb25zb2xlIHZzLiBTY3JpcHRzIHZzLiBNYXJrZG93biB2cy4gUiBOb3RlYm9va3MKCldlbGNvbWUgdG8gdXNpbmcgUi4gVGhpcyBzdWJzZWN0aW9uIHdpbGwgZXhwbGFpbiB0aGUgYmFzaWNzIGFib3V0IFIuIEZpcnN0LCBsZXRzIGRpc2N1c3MgdGhlIGRpZmZlcmVudCB3YXlzIHRvIHdyaXRlIFIgY29kZSwgYXMgdGhlcmUgYXJlIChhdCBsZWFzdCkgNToKCi0gdHlwZSBpdCBkaXJlY3RseSBpbnRvIHRoZSBjb25zb2xlIChnZW5lcmFsbHkgbm90IHJlY29tbWVuZGVkKQotIHNhdmUgaXQgYXMgYSBzY3JpcHQgKGJldHRlcikgKioqbm90ZSB0aGF0IHNjcmlwdCBjYW4gcmVmZXIgdG8gYW55IG9mIHRoZSBiZWxvdywgYnV0IGluIHRoaXMgY2FzZSBpcyBiZWluZyB1c2VkIHRvIGRlc2NyaWJlIGEgc2NyaXB0IHRoYXQgZG9lc24ndCBnZW5lcmF0ZSBhIG5vdGVib29rKioqCi0gc2F2ZSBpdCBhcyBhbiBSIE1hcmtkb3duIChiZXR0ZXIgc3RpbGwpIC0gdGhpcyBhbGxvd3MgeW91IHRvIG1ha2UgYmVhdXRpZnVsIGRvY3VtZW50cwotIHNhdmUgaXQgYXMgYW4gUiBOb3RlYm9vayAoYXJndWFibHkgYmV0dGVyIHRoYW4gUiBNYXJrZG93bikgLSB0aGlzIGFsbG93cyB5b3UgdG8gbWFrZSBiZWF1dGlmdWwgZG9jdW1lbnRzLCBhbmQgaXMgcXVpY2tlcgoKCiMjIyBUaGUgQ29uc29sZQoKQXQgdGhlIGJvdHRvbSBsZWZ0IG9mIFJTdHVkaW8geW91IHNob3VsZCBoYXZlIGEgY29uc29sZSB0aGF0IGxvb2tzIHNvbWV0aGluZyBsaWtlIHdoYXQncyBoaWdobGlnaHRlZCBpbiA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5yZWQ8L3NwYW4+IGJlbG93OgoKPGltZyBzcmM9InJCYXNpY3MvY29uc29sZS5wbmciPgoKWW91IGNhbiB0eXBlIHN0cmFpZ2h0IGludG8gdGhlIGNvbnNvbGUsIHRvIGdldCBhIHJlc3VsdC4gWW91IGNhbiBzY3JvbGwgdGhyb3VnaCB5b3VyIHByZXZpb3VzIGNvbW1hbmRzIGJ5IHByZXNzaW5nIHRoZSB1cCBhcnJvdyBpbiB0aGUgY29uc29sZS4gRWFjaCB0aW1lIGNvZGUgaXMgcnVuIGluIHRoZSBjb25zb2xlIGl0IHVwZGF0ZXMgdGhlIGVudmlyb25tZW50IGluIHRoZSB0b3AgcmlnaHQgb2YgUi1TdHVkaW86Cgo8aW1nIHNyYz0ickJhc2ljcy9lbnZpcm9ubWVudC5wbmciLz4KCiMjIyBTY3JpcHRzCgpUaGUgd29yZCAic2NyaXB0IiBjYW4gYmUgaW50ZXJwcmV0ZWQgc3BlY2lmaWNhbGx5LCB0byByZWZlciB0byBhIHR5cGUgb2YgUiBmaWxlIHRoYXQgaW5jbHVkZXMgYSBsb3Qgb2YgY29kZSwgb3IgZ2VuZXJhbGx5IHRvIHJlZmVyIHRvIGFueSBmaWxlIHRoYXQgaW5jbHVkZXMgYm90aCBSIGNvZGUgYW5kIGNvZGUgdGhhdCBhbGxvd3MgeW91IG1ha2UgYSBuaWNlIGxvb2tpbmcgcmVwb3J0LiBJbiB0aGlzIHN1YnNlY3Rpb24sIHdlIHdpbGwgYmUgZm9jdXNpbmcgb24gInNjcmlwdCIgYXMgYSBwYXJ0aWN1bGFyIHR5cGUgb2YgZmlsZS4gVG8gY3JlYXRlIGEgc2NyaXB0LCBjbGljayBvbiAqKkZpbGUgLT4gTmV3IEZpbGUgLT4gUiBTY3JpcHQqKgoKPGltZyBzcmM9InJCYXNpY3MvbmV3U2NyaXB0LnBuZyIvPgoKWW91IHdpbGwgdGhlbiBiZSBzaG93biBhIGJsYW5rIHNjcmlwdCwgaW4gd2hpY2ggeW91IGNhbiB3cml0ZSBhIHNlcmllcyBvZiBmdW5jdGlvbnMsIGFuZCB0aGVuIHJ1biB0aGVtLiBUbyBydW4gdGhlIGxpbmVzIG9mIGNvZGUsIHNlbGVjdCBhIGxpbmUsIGFuZCB0aGVuIHByZXNzIENUUkwtRU5URVIsIG9yIGhpZ2hsaWdodCBhIGNodW5rIG9mIGNvZGUgYW5kIHRoZW4gcHJlc3MgQ1RSTC1FTlRFUi4gSW4gZWl0aGVyIGNhc2UsIHRoZSBjb2RlIHdpbGwgYmUgc2VudCB0byB0aGUgY29uc29sZSBhbmQgcnVuIHRoZXJlLiAKCkFuIGFkdmFudGFnZSBvZiBhIHNjcmlwdCBvdmVyIGp1c3QgdXNpbmcgdGhlIGNvbnNvbGUgaXMgdGhhdCB5b3UgY2FuIGFuYWx5c2UgeW91ciBkYXRhIGluIGJvdGggKnN0cnVjdHVyZWQgYW5kIGNvbXBsZXggd2F5cyogd2hpY2ggaXMgZGlmZmljdWx0IGlmIHlvdSBhcmUgdHlwaW5nIGNvZGUgZGlyZWN0bHkgaW50byB0aGUgY29uc29sZS4KCiMjIyBSIE1hcmtkb3duCgpBcyBoaWdobGlnaHRlZCBhYm92ZSwgUiBNYXJrZG93biBpcyBhIHR5cGUgb2YgInNjcmlwdCIgaW4gdGhlIGdlbmVyYWwgc2Vuc2Ugb2YgdGhlIHdvcmQsIGJ1dCBhbGxvd3MgeW91IHRvIGNyZWF0ZSBiZWF1dGlmdWwgLmh0bWwgbm90ZWJvb2tzICguaHRtbCBmaWxlcyBhcmUgd2hhdCBpbnRlcm5ldCBwYWdlcyBhcmUgYmFzZWQgb24pLiBZb3UgYXJlIGluIGZhY3QgcmVhZGluZyBhbiBleGFtcGxlIG9mIHdoYXQgY2FuIGJlIHByb2R1Y2VkIGJ5IFIgTWFya2Rvd24gKGFuZCBSIE5vdGVib29rcykuIFRvIG1ha2UgYW4gUiBNYXJrZG93biBmaWxlLCBjbGljayBvbiAqKkZpbGUgLT4gTmV3IEZpbGUgLT4gUiBNYXJrZG93bioqLiBZb3Ugd2lsbCBiZSBhc2tlZCBmb3IgYSB0aXRsZSwgYXV0aG9yIGFuZCB3aGF0IG91dHB1dCB5b3Ugd291bGQgbGlrZS4gSSB3b3VsZCBzdWdnZXN0ICJmaXJzdCBtYXJrZG93biIsIHlvdXIgbmFtZSBhbmQgImh0bWwiIGFzIHRoZSByZXNwZWN0aXZlIGFuc3dlcnMuIFlvdSBzaG91bGQgdGhlbiBzZWUgc29tZXRoaW5nIGxpa2U6Cgo8aW1nIHNyYz0ickJhc2ljcy9tYXJrZG93bi5wbmciLz4KCioqVGhlIGZvbGxvd2luZyBwb2ludHMgYXBwbHkgdG8gYm90aCBSIE1hcmtkb3duIGFuZCBSIE5vdGVib29rcyoqCgpJZiB5b3UgbG9vayBhYm92ZSwgeW91IG1heSBub3RpY2UgdGhhdCB0aGVyZSBhcmUgMiB0eXBlcyBvZiBjb2RlOiBNYXJrZG93biAodG8gd3JpdGUgYSBuaWNlIGxvb2tpbmcgcmVwb3J0KSBhbmQgUiAoaW4gZ3JleSBjaHVua3MpLiBJIHRoaW5rIHRoZXNlIGFyZSB3ZWxsIGV4cGxhaW5lZCBoZXJlOiBodHRwczovL3d3dy5yc3R1ZGlvLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAxNS8wMi9ybWFya2Rvd24tY2hlYXRzaGVldC5wZGYgc28gSSdsbCBqdXN0IGV4cGxhaW4gdGhhdCBSIE1hcmtkb3ducyBydW4gYWxsIHRoZSBjb2RlIGluIHRoZSBjaHVua3MgZWFjaCB0aW1lIHRoZXkgZ2VuZXJhdGUgdGhlIG91dHB1dCBmaWxlIChlLmcuIGh0bWwgZmlsZSkuIFRoaXMgaXMgaW1wb3J0YW50IHRvIGtub3csIGJlY2F1c2UgUiBOb3RlYm9va3MgZG8gKipub3QqKiBkbyB0aGlzLgoKIyMjIFIgTm90ZWJvb2tzCgpSIE5vdGVib29rcyBjYW4gYmUgY3JlYXRlZCBieSBjbGlja2luZyBvbiAqKkZpbGUgLT4gTmV3IEZpbGUgLT4gUiBOb3RlYm9vayoqLiBUaGV5IGxvb2sgcXVpdGUgc2ltaWxhciB0byBSIE1hcmtkb3ducywgYnV0IGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGUgdGhlIC5odG1sIG91dHB1dCAqKmVhY2ggdGltZSB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2sqKi4gVGhlIG91dHB1dCBmaWxlIHdpbGwgYmUgYSAqKi5uYi5odG1sKiogZmlsZSBpbiB0aGUgc2FtZSBmb2xkZXIgYXMgeW91ciBub3RlYm9vay4gCgoqKipWZXJ5IGltcG9ydGFudGx5KioqIC0gdGhlICoubmIuaHRtbCogZmlsZSB3aWxsIGJlIGJ1aWx0IGJhc2VkIG9uIHdoYXQgaGFwcGVuZWQgdGhlIGxhc3QgdGltZSB5b3UgcnVuIGVhY2ggUiBjaHVuay4gSWYgeW91IG5ldmVyIHJhbiB0aGUgUiBDaHVuaywgdGhlbiB0aGUgbmIuaHRtbCBmaWxlIHdpbGwgbm90IHVzZSB0aGUgb3V0cHV0IGZyb20gdGhhdCBjaHVuay4gKipUaGlzIG1ha2VzIFIgTm90ZWJvb2tzIHF1aWNrZXIgdGhhbiBSIE1hcmtkb3ducywgYmVjYXVzZSB5b3UgZG9uJ3QgaGF2ZSB0byBnZW5lcmF0ZSB0aGUgb3V0cHV0IGZyb20gc2NyYXRjaCBlYWNoIHRpbWUsIGJ1dCB0aGVyZSBpcyBhIHJpc2sgb2YgeW91IGZvcmdldHRpbmcgdG8gcnVuIGEgY2h1bmsgYWZ0ZXIgY2hhbmdpbmcgaXQqKi4KCiMjIEZ1bmRhbWVudGFsJ3Mgb2YgUgoKUiBhbGxvd3MgeW91IHRvIGNvbXBsZXRlIGNhbGN1bGF0aW9ucywgc28gbGV0cyBzdGFydCB3aXRoIHRoYXQuIFR5cGUgaW50byB5b3VyIG1hcmtkb3duIG9yIHNjcmlwdAoKT2Z0ZW4sIHlvdSBjYW4gdXNlIFIgYXMgYSBjYWxjdWxhdG9yLCBmb3IgZXhhbXBsZToKYGBge3J9CjUgKyAyCmBgYAoKSXQncyBoZWxwZnVsIHRvIHN0b3JlIHRoZXNlIGNhbGN1bGF0aW9ucyBpbnRvICoqb2JqZWN0cyoqOgpgYGB7cn0KYSA8LSA1ICsgMiAgIyB0aGlzIGlzIGV4YWN0bHkgdGhlIHNhbWUgYXMgd3JpdGluZyBhID0gNSArIDIsIGJ1dCA8LSBpcyBlbmNvdXJhZ2VkIGluIFIgdG8gYXZvaWQgY29uZnVzaW9uIHdpdGggb3RoZXIgdXNlcyBvZiA9IChlLmcuID09IG9wZXJhdG9yIHdoZW4geW91IGFyZSBjb21wYXJpbmcgaWYgdHdvIHZhbHVlcyBhcmUgaWRlbnRpY2FsKQojIHRoaXMgIyBpcyBzdGFydGluZyBhIGNvbW1lbnQsIGNvZGUgdGhhdCB3aWxsIGJlIGlnbm9yZWQgYnV0IGFsbG93cyB5b3UgdG8gYW5ub3RhdGUgeW91ciB3b3JrCmEgIyB0byBzaG93IHdoYXQgdGhlIHZhbHVlIDcgaXMgbm93IHN0b3JlZCBpbiB0aGUgb2JqZWN0ICJhIgpgYGAKCgpUaGlzIG1lYW5zIHRoYXQgeW91IGNhbiBjb21wYXJlIG9iamVjdHMgdG8gZWFjaCBvdGhlciBsYXRlcgoKYGBge3J9CmIgPC0gMgpiIC0gYQpjIDwtIGItYQpjICMgdG8gc2hvdyB3aGF0IGMgaXMKYGBgCgpTb21lIGFkdmljZS9ydWxlcyBmb3IgKipPYmplY3RzKio6CgotIFlvdSBjYW5ub3QgaGF2ZSBhIHNwYWNlIGluIGFuIG9iamVjdCBuYW1lLiAibXkgb2JqZWN0IiB3b3VsZCBiZSBhbiBpbnZhbGlkIG9iamVjdCBuYW1lLgotIG9iamVjdCBuYW1lcyBhcmUgKioqY2FzZS1zZW5zaXRpdmUqKiosIHNvIGlmIHlvdXIgb2JqZWN0IGlzIGNhbGxlZCAiTXlPYmplY3QiIHlvdSBjYW5ub3QgcmVmZXIgdG8gaXQgYXMgIm15b2JqZWN0Ii4KLSAiLiIgYW5kICJfIiBhcmUgYWNjZXB0YWJsZSBjaGFyYWN0ZXJzIGluIHZhcmlhYmxlIG5hbWVzLgotIHlvdSBjYW4gb3ZlcndyaXRlIG9iamVjdHMgaW4gdGhlIHNhbWUgd2F5IHRoYXQgeW91IGRlZmluZSBhbiBvYmplY3QKCmBgYHtyfQp0aGlzX29iamVjdCA8LSA1CnRoaXNfb2JqZWN0ICMgdG8gc2hvdyB3aGF0IHRoZSBvYmplY3QgdmFsdWUgaXMKdGhpc19vYmplY3QgPC0gMTAgIyBvdmVyd3JpdGVzIHRoaXNfb2JqZWN0CnRoaXNfb2JqZWN0ICMgc2hvdWxkIG5vdyBzaG93IDEwCmBgYAoKLSBiZSBjYXJlZnVsIHRvIG5vdCBnaXZlIGFuIG9iamVjdCB0aGUgc2FtZSBuYW1lIGFzIGEgZnVuY3Rpb24hIFRoaXMgd2lsbCBvdmVyd3JpdGUgdGhlIGZ1bmN0aW9uLiBUbyBjaGVjayBpZiB0aGUgbmFtZSBhbHJlYWR5IGV4aXN0cywgeW91IGNhbiBzdGFydCB0eXBpbmcgaXQgYW5kIHByZXNzIHRhYi4gU28gdHlwaW5nICJ0LnRlIiBhbmQgcHJlc3NpbmcgdGhlIHRhYiB3aWxsIGdpdmUgeW91ICJ0LnRlc3QiCgoKIyMjIEZ1bmN0aW9ucwoKSW4gYSB2YXJpZXR5IG9mIGNvZGluZyBsYW5ndWFnZXMgbGlrZSBSLCAqKmZ1bmN0aW9ucyoqIGFyZSBsaW5lcyBvZiBjb2RlIHlvdSBjYW4gYXBwbHkgZWFjaCB0aW1lIHlvdSBjYWxsIHRoZSBmdW5jdGlvbiwgYW5kIGFwcGx5IGl0IHRvICoqaW5wdXQqKiB0byBnZXQgYW4gKipvdXRwdXQqKi4gSWYgeW91IHdhbnRlZCB0byBtYWtlIGEgZnVuY3Rpb24gdGhhdCBtdWx0aXBsaWVkIG51bWJlcnMgYnkgMiwgaXQgd291bGQgbG9vayBzb21ldGhpbmcgbGlrZToKCmBgYHtyfQp0aW1lc190d28gPC0gZnVuY3Rpb24oaW5wdXQpeyAgIyBEZWZpbmUgeW91ciBmdW5jdGlvbiBieSBzdGF0aW5nIGl0J3MgbmFtZSwgYW5kIHRoZW4gdXNpbmcgPC0gdG8gZGVzY3JpYmUgaXQKICBvdXRwdXQgPSBpbnB1dCAqIDIgICAgICAgICAgICMgY3JlYXRlcyBhbiBvdXRwdXQgb2JqZWN0IHRoYXQgaXMgdGhlIGlucHV0IG9iamVjdCAoc2VlIGxpbmUgYWJvdmUpIHggMgogIHJldHVybiAob3V0cHV0KSAgICAgICAgICAgICAgIyBnaXZlcyB0aGUgb3V0cHV0IGJhY2sgdG8gdGhlIHVzZXIgd2hlbiB0aGV5IHJ1biB0aGUgZnVuY3Rpb24KfQp0aW1lc190d28oNCkgICAgICAgICAgICAgICAgICAgIyBzaG91bGQgZ2l2ZSB5b3UgOApgYGAKClRoZSAqKmdyZWF0IG5ld3MqKiBpcyB0aGF0IHlvdSBkb24ndCBuZWVkIHRvIHdyaXRlIGZ1bmN0aW9ucyA5OSUgb2YgdGhlIHRpbWUgaW4gUiwgdGhlcmUgYXJlIGEgd2lkZSB2YXJpZXR5IG9mIGZ1bmN0aW9ucyB0aGF0IGFyZSBhdmFpbGFibGUuIFNvbWUgb2Ygd2hpY2ggd2lsbCBiZSB1c2VkIGluIHRoZSBuZXh0IHNlY3Rpb24uCgojIyMgVHlwZXMgb2YgT2JqZWN0cwoKIyMjIyBWZWN0b3JzCgoqKlZlY3RvcnMqKiBzdG9yZSBhIHNlcmllcyBvZiB2YWx1ZXMuIE9mdGVuIHRoZXNlIHdpbGwgYmUgYSBzZXJpZXMgb2YgbnVtYmVyczoKCmBgYHtyfQpudW1lcmljX3ZlY3RvciA9IGMoMSwyLDMpCm51bWVyaWNfdmVjdG9yCmBgYAoKVGhlICJjIiBhYm92ZSBpcyBzaG9ydCBmb3IgImNvbWJpbmUiIGFzIHlvdSdyZSBjb21iaW5pbmcgdmFsdWVzIHRvZ2V0aGVyIHRvIG1ha2UgdGhpcyB2ZWN0b3IuIAoqKlN0cmluZ3MqKiBhcmUgdmFsdWVzIHRoYXQgaGF2ZSBjaGFyYWN0ZXJzIChhbHNvIGtub3duIGFzIGxldHRlcnMpIGluIHRoZW0uIExldHMgc2VlIGlmIHdlIGNhbiBtYWtlIGEgdmVjdG9yIG9mICoqc3RyaW5ncyoqOgoKYGBge3J9CnN0cmluZ192ZWN0b3IgPSBjKCJhIiwgImIiLCAiYyIpCnN0cmluZ192ZWN0b3IKYGBgCgpMb29rcyBsaWtlIHdlIGNhbi4gQnV0IHdoYXQgaGFwcGVucyBpZiB5b3UgbWl4IHN0cmluZ3MgYW5kIG51bWJlcnMgaW4gYSAqKnZlY3RvcioqOgoKYGBge3J9Cm1peGVkX3ZlY3RvciA9IGMoImEiLCAxLCAiYyIpCm1peGVkX3ZlY3RvcgpgYGAKClIgc2VlbXMgdG8gYmUgaGFwcHkgdG8gcHV0IHRoZW0gaW50byBhIHNpbmdsZSB2ZWN0b3IuIEJ1dCB0aGVyZSBhcmUgZGlmZmVyZW50IHR5cGVzIG9mIHZhbHVlcyBhbmQgdmVjdG9ycywgc28gbGV0cyBhc2sgUiB3aGF0IGVhY2ggdHlwZSBvZiAodXNpbmcgdGhlICJ0eXBlb2YiICoqZnVuY3Rpb24qKikgdmVjdG9ycyB3ZSBoYXZlIGFib3ZlOgoKYGBge3J9CnR5cGVvZihudW1lcmljX3ZlY3RvcikKdHlwZW9mKHN0cmluZ192ZWN0b3IpCnR5cGVvZihtaXhlZF92ZWN0b3IpCmBgYAoKVGhlIG51bWVyaWMgdmVjdG9yIGlzIGEgImRvdWJsZSIgdmVjdG9yLiAqKkRvdWJsZSoqIHJlZmVycyB0byB0aGUgZmFjdCB0aGF0IHRoZSBudW1iZXJzICpjYW4gaW5jbHVkZSBkZWNpbWFscyosIGFzIG9wcG9zZWQgdG8gKippbnRlZ2VyKiogbnVtYmVycyAqd2hpY2ggaGF2ZSB0byBiZSB3aG9sZSBudW1iZXJzKi4gSW50ZXJlc3RpbmdseSwgUiBoYXMgYXNzdW1lZCB0aGUgbGlzdCBvZiBudW1iZXJzIHNob3VsZCBiZSAqKmRvdWJsZSoqIHJhdGhlciB0aGFuICoqaW50ZWdlcioqLCB3aGljaCBzZWVtcyBsaWtlIHRoZSBtb3JlIHJvYnVzdCB0aGluZyB0byBkbywgYXMgaW50ZWdlciBudW1iZXJzIGNhbiBhbHdheXMgYmUgZG91YmxlLCBidXQgZG91YmxlIG51bWJlcnMgY2FuJ3QgYWx3YXlzIGJlIGludGVnZXJzLgoKIyMjIyBEYXRhIGZyYW1lcwoKKipEYXRhIGZyYW1lcyoqIGxvb2sgbGlrZSB0YWJsZXMsIGluIHdoaWNoIHlvdSBoYXZlIGEgc2VyaWVzIG9mIGNvbHVtbnMgd2l0aCAqKmhlYWRlcnMqKiB0aGF0IGRlc2NyaWJlIGVhY2ggY29sdW1uLiAKClNvbWUgZGF0YSBmcmFtZXMgYXJlIGFscmVhZHkgbG9hZGVkIGludG8gUlN0dWRpbyB3aGVuIHlvdSBydW4gaXQsIHN1Y2ggYXMgdGhlICJtcGciIGRhdGFmcmFtZS4gVG8gbG9vayBhdCBpdCwganVzdCB0eXBlIGluIGl0J3MgbmFtZToKCmBgYHtyfQptcGcKYGBgCjxpbWcgc3JjPSJyQmFzaWNzL21wZ1RhYmxlLnBuZyIvPgoqTm90ZSB0aGF0IHlvdSBtYXkgc2VlIDIgdGFibGVzIGFib3ZlLCBidXQgdGhleSBzaG91bGQgYmUgaWRlbnRpY2FsIGlmIHNvKgoKVGhlICoqbXBnKiogZGF0YWZyYW1lIGhhcyBpbmZvcm1hdGlvbiBhYm91dCBhIHZhcmlldHkgb2YgY2FycywgdGhlaXIgbWFudWZhY3R1cmVycywgbW9kZWxzLCBhcyBkZXNjcmliZWQgaHR0cHM6Ly9nZ3Bsb3QyLnRpZHl2ZXJzZS5vcmcvcmVmZXJlbmNlL21wZy5odG1sLiBZb3Ugd2lsbCBuZWVkIHRvIHJlZmVyIHRvIGRhdGEgZnJhbWVzIGFuZCB0aGVpciBjb2x1bW5zLCB0aGUgY29udmVudGlvbiBmb3IgdGhpcyBiZWluZyB0byB3cml0ZSBkYXRhIGZyYW1lJGNvbHVtbi4gTGV0cyBkbyB0aGlzIHRvIHNlZSB3aGF0J3MgaW4gdGhlICJtYW51ZmFjdHVyZXIiIGNvbHVtbjoKCmBgYHtyfQptcGckbWFudWZhY3R1cmVyCmBgYAoKCiMjIyBQYWNrYWdlcwoKV2hpbHN0IGEgbG90IG9mIHRoZSBmdW5jdGlvbnMgeW91IHdpbGwgbmVlZCBhcmUgaW4gdGhlICpiYXNlKiBjb2RlIHRoYXQgaXMgYWN0aXZlIGJ5IGRlZmF1bHQsIHlvdSB3aWxsIGF0IHRpbWVzIG5lZWQgZXh0cmEgcGFja2FnZXMgb2YgY29kZSB0byBkbyBtb3JlIHBvd2VyZnVsIHRoaW5ncy4gQSBjb21tb25seSB1c2VkIHBhY2thZ2UgaXMgZ2dwbG90MiBbaHR0cHM6Ly9nZ3Bsb3QyLnRpZHl2ZXJzZS5vcmcvXSwgd2hpY2ggYWxsb3dzIHlvdSB0byBtYWtlICoqKmJlYXV0aWZ1bCoqKiBmaWd1cmVzIGluIFIuIFRvIHVzZSBnZ3Bsb3QyIHVzZSBuZWVkIHRvICoqaW5zdGFsbCoqIGl0IGFuZCB0aGVuIGxvYWQgaXQgZnJvbSB0aGUgKipsaWJyYXJ5KioKCmBgYHtyfQppZighcmVxdWlyZShnZ3Bsb3QyKSl7aW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpfQpsaWJyYXJ5KGdncGxvdDIpCmBgYAoKTm93IHRoYXQgeW91IGhhdmUgYSBwYWNrYWdlIGZvciBtYWtpbmcgYmVhdXRpZnVsIHBsb3RzLCBsZXRzIGxlYXJuIGFib3V0ICJpbnRlbGxpZ2VudCBjb3B5IGFuZCBwYXN0ZSIgdG8gbWFrZSB1c2Ugb2YgaXQuCgojIyMgSW50ZWxsaWdlbnQgY29weSBhbmQgcGFzdGUKClBlb3BsZSBleHBlcmllbmNlZCB3aXRoIGNvZGluZyAqKipkbyBub3Qgd3JpdGUgYWxsIHRoZWlyIGNvZGUgZnJvbSBtZW1vcnkqKiouIFRoZXkgb2Z0ZW4gY29weSBhbmQgcGFzdGUgY29kZSBmcm9tIHRoZSBpbnRlcm5ldCBhbmQvb3IgZnJvbSB0aGVpciBvbGQgc2NyaXB0cy4gU28sIGFzc3VtaW5nIHlvdSd2ZSBpbnN0YWxsZWQgYW5kIGxvYWRlZCBnZ3Bsb3QyIGFzIGRlc2NyaWJlZCBhYm92ZSwgbGV0cyBjb3B5IGFuZCBwYXN0ZSBjb2RlIGZyb20gdGhlaXIgd2Vic2l0ZSAoYXMgb2YgU2VwdGVtYmVyIDIwMjI7IGh0dHBzOi8vZ2dwbG90Mi50aWR5dmVyc2Uub3JnLykKCmBgYHtyfQpnZ3Bsb3QobXBnLCBhZXMoZGlzcGwsIGh3eSwgY29sb3VyID0gY2xhc3MpKSArIAogIGdlb21fcG9pbnQoKQpgYGAKR29vZCBuZXdzIGlzIHRoYXQgd2UgaGF2ZSBhIG5pY2UgbG9va2luZyBmaWd1cmUuIEJ1dCBub3cgd2UgbmVlZCB0byB3b3JrIG91dCBob3cgdG8gdW5kZXJzdGFuZCB0aGUgY29kZSB3ZSd2ZSBjb3BpZWQgc28gdGhhdCB5b3UgY2FuIGFwcGx5IGl0IHRvIHlvdXIgb3duIHNjcmlwdHMuIFRoZXJlJ3MgYSBsb3QgdG8gdW5wYWNrLCBzbyBtYWtpbmcgdGhlIGNvZGUgbW9yZSAqKnZlcnRpY2FsKiogY2FuIGhlbHAgeW91IGJyZWFrIGl0IGRvd24gYW5kIGNvbW1lbnQgaXQgb3V0LiBVc2luZyB0aGUgYmVsb3cgYW5kIGEgZGVzY3JpcHRpb24gb2YgdGhlIG1wZyBkYXRhZnJhbWUgKGh0dHBzOi8vZ2dwbG90Mi50aWR5dmVyc2Uub3JnL3JlZmVyZW5jZS9tcGcuaHRtbCksIGNhbiB5b3UgY29tbWVudCBpdCBvdXQKCmBgYHtyfQpnZ3Bsb3QoICAgICAgICAgICAgICMgUiB3aWxsIGtlZXAgbG9va2luZyBhdCB5b3VyIGNvZGUgdW50aWwgYWxsIHRoZSBvcGVuIGJyYWNrZXRzIGhhdmUgYmVlbiBjbG9zZWQpCiAgbXBnLCAgICAgICAgICAgICAgIwogIGFlcyggICAgICAgICAgICAgICMKICAgIGRpc3BsLCAgICAgICAgICAjCiAgICBod3ksICAgICAgICAgICAgIwogICAgY29sb3VyID0gY2xhc3MgICMKICApCikgKyAgICAgICAgICAgICAgICAgIyBSIHdpbGwgbG9vayB0byB0aGUgbmV4dCBsaW5lIGlmIHlvdSBlbmQgYSBsaW5lIHdpdGggKwpnZW9tX3BvaW50KCkgICAgICAgICMKYGBgCgpIZXJlJ3MgaG93IEkgd291bGQgY29tbWVudCBpdCBvdXQ6CgpgYGB7cn0KZ2dwbG90KAogIG1wZywgICAgICAgICAgICAgICMgZGF0YWZyYW1lCiAgYWVzKCAgICAgICAgICAgICAgIyBhZXN0aGV0aWMgcHJvcGVydGllcwogICAgZGlzcGwsICAgICAgICAgICMgeC1heGlzCiAgICBod3ksICAgICAgICAgICAgIyB5LWF4aXMKICAgIGNvbG91ciA9IGNsYXNzICAjIHdoaWNoIGNvbHVtbiBJIHdpbGwgYmFzZSB0aGUgY29sb3Igb24gKG9mdGVuICJjb2xvciIgaXMgc2FmZXIgc3BlbGxpbmcgaW4gY29kZSkKICApCikgKyAKZ2VvbV9wb2ludCgpICAgICAgICAjIHdoYXQgSSB3b3VsZCBsaWtlIGRyYXduIG9uIChhcyBvcHBvc2VkIHRvIGJveHBsb3RzLCBsaW5lcywgZXRjLikKYGBgCgoqKkZvcm1hdHRpbmcgY29kZSBsaWtlIGFib3ZlIHRvIGJlIGNsZWFyZXIgdG8gcmVhZCBpcyB1c2VmdWwgd2hlbiBzaGFyaW5nIHlvdXIgc2NyaXB0cyB3aXRoIG90aGVyIHJlc2VhcmNoZXJzIHNvIHRoYXQgdGhleSBjYW4gdW5kZXJzdGFuZCBpdCEqKgoKCk5vdyB0byB1bmRlcnN0YW5kIHRoZSBhYm92ZSBjb2RlLCB0cnkgcnVubmluZyBpdCBhZnRlciBjaGFuZ2luZyBsaW5lcy4gRm9yIGV4YW1wbGUsIHdoYXQgaGFwcGVucyBpZiB5b3UgY2hhbmdlIHRoZSB4LWF4aXM6CgpgYGB7cn0KZ2dwbG90KAogIG1wZywgICAgICAgICAgICAgICMgZGF0YWZyYW1lCiAgYWVzKCAgICAgICAgICAgICAgIyBhZXN0aGV0aWMgcHJvcGVydGllcwogICAgY3R5LCAgICAgICAgICAgICMgeC1heGlzIC0gdXBkYXRlZAogICAgaHd5LCAgICAgICAgICAgICMgeS1heGlzCiAgICBjb2xvdXIgPSBjbGFzcyAgIyB3aGljaCBjb2x1bW4gSSB3aWxsIGJhc2UgdGhlIGNvbG9yIG9uIChvZnRlbiAiY29sb3IiIGlzIHNhZmVyIHNwZWxsaW5nIGluIGNvZGUpCiAgKQopICsgCmdlb21fcG9pbnQoKSAgICAgICAgIyB3aGF0IEkgd291bGQgbGlrZSBkcmF3biBvbiAoYXMgb3Bwb3NlZCB0byBib3hwbG90cywgbGluZXMsIGV0Yy4KCmBgYApUbyBtYWtlIGJlYXV0aWZ1bCBmaWd1cmVzIGluIFIsIHlvdSBjYW4gbGFyZ2VseSBnb29nbGUgdGhlIHR5cGUgb2YgcGxvdCB5b3Ugd2FudCwgY29weSB0aGUgZXhhbXBsZSBjb2RlIHRoYXQgdGhlIHdlYnNpdGUgaGFzLCBhbmQgdGhlbiBzd2FwIGluIHRoZSByZWxldmFudCBmZWF0dXJlcyBmb3IgeW91ciBwbG90LiBUaGlzIHByaW5jaXBsZSBvZiBjb3B5aW5nIGFuZCBwYXN0aW5nIGNvZGUsIChtYWtpbmcgaXQgdmVydGljYWwgdG8gbWFrZSBpdCBsZWdpYmxlIGlzIG5vdCBuZWNlc3NhcnksIGJ1dCBjYW4gYmUgaGVscGZ1bCksIGFuZCB0aGVuIGVkaXRpbmcgaXQgdG8gd29yayBmb3IgeW91ciBvd24gc2NyaXB0IGlzIGFuICoqZXNzZW50aWFsIHNraWxsKiogdG8gc3BlZWQgdXAgeW91ciBjb2Rpbmcu